# -*- coding: utf-8 -*-
# (c) 2015 Mikel Arregi - AvanzOSC
# (c) 2015 Oihane Crucelaegui - AvanzOSC
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html

from odoo import _, api, exceptions, fields, models
import odoo.addons.decimal_precision as dp
from odoo.tools.float_utils import float_compare
from odoo.exceptions import UserError
import math


class move_update_qty(models.TransientModel):
    _name = 'move.update.qty'

    update_qty = fields.Float(string=u'更新数', digits=dp.get_precision('Product Unit of Measure'))

    @api.multi
    def update_qty_form_move(self):
        move = self.env['stock.move'].browse(self.env.context['active_id'])
        return self._update_qty_form_move(move)

    def _update_qty_form_move(self, move):
        move.picking_id.mapped('pack_operation_ids').unlink()
        quants = []
        # 如果是调拨单的话
        if move.picking_id:
            move.picking_id.recompute_pack_op = True
            move.quants_unreserve()
            move.picking_id.do_unreserve()
            move.product_uom_qty = self.update_qty
            if move.procurement_id:
                moves = self.env['stock.move'].search([('procurement_id', '=', move.procurement_id.id)])
                sum_qty = 0
                for pro_move in moves:
                    sum_qty += pro_move.product_uom_qty
                move.procurement_id.product_qty = sum_qty
        # 如果是生产单的话
        if move.production_id:
            change_qty = self.update_qty - move.product_uom_qty + move.production_id.product_qty
            self.change_prod_qty(move.production_id, change_qty)
            if move.procurement_id:
                move.procurement_id.product_qty = change_qty
            # if move.production_id.procurement_id:
            #     move.production_id.procurement_id.product_qty = change_qty
        if move.move_dest_id:
            self._update_qty_form_move(move.move_dest_id)
        return True

    @api.model
    def default_get(self, fields):
        res = super(move_update_qty, self).default_get(fields)
        move = self.env['stock.move'].browse(self.env.context['active_id'])
        res.update({'update_qty': move.product_uom_qty})
        res = self._convert_to_write(self._convert_to_cache(res))
        return res

    @api.model
    def _update_product_to_produce(self, production, qty):
        production_move = production.move_finished_ids.filtered(
            lambda x: x.product_id.id == production.product_id.id and x.state not in ('done', 'cancel'))
        if production_move:
            production_move.write({'product_uom_qty': qty})
        else:
            production_move = production._generate_finished_moves()
            production_move = production.move_finished_ids.filtered(
                lambda x: x.state not in ('done', 'cancel') and production.product_id.id == x.product_id.id)
            production_move.write({'product_uom_qty': qty})

    @api.multi
    def change_prod_qty(self, mrp, qty):
        for wizard in self:
            production = mrp
            produced = sum(production.move_finished_ids.mapped('quantity_done'))
            if qty < produced:
                raise UserError(
                    _(u"你已经完成 %d. 输入的数量必须大于 %d ") % (produced, produced))
            production.write({'product_qty': qty})
            done_moves = production.move_finished_ids.filtered(
                lambda x: x.state == 'done' and x.product_id == production.product_id)
            qty_produced = production.product_id.uom_id._compute_quantity(sum(done_moves.mapped('product_qty')),
                                                                          production.product_uom_id)
            # factor = production.product_uom_id._compute_quantity(production.product_qty - qty_produced,
            #                                                      production.bom_id.product_uom_id) / production.bom_id.product_qty
            # boms, lines = production.bom_id.explode(production.product_id, factor,
            #                                         picking_type=production.bom_id.picking_type_id)
            # 更新生产单明细
            # for line, line_data in lines:
            #     production._update_raw_move(line, line_data)
            # operation_bom_qty = {}
            # for bom, bom_data in boms:
            #     for operation in bom.routing_id.operation_ids:
            #         operation_bom_qty[operation.id] = bom_data['qty']
            self._update_product_to_produce(production, production.product_qty - qty_produced)
            # moves = production.move_raw_ids.filtered(lambda x: x.state not in ('done', 'cancel'))
            # moves.do_unreserve()
            # moves.action_assign()
            # for wo in production.workorder_ids:
            #     operation = wo.operation_id
            #     if operation_bom_qty.get(operation.id):
            #         cycle_number = math.ceil(
            #             operation_bom_qty[operation.id] / operation.workcenter_id.capacity)  # TODO: float_round UP
            #         wo.duration_expected = (operation.workcenter_id.time_start +
            #                                 operation.workcenter_id.time_stop +
            #                                 cycle_number * operation.time_cycle * 100.0 / operation.workcenter_id.time_efficiency)
            #     if production.product_id.tracking == 'serial':
            #         quantity = 1.0
            #     else:
            #         quantity = wo.qty_production - wo.qty_produced
            #         quantity = quantity if (quantity > 0) else 0
            #     wo.qty_producing = quantity
            #     if wo.qty_produced < wo.qty_production and wo.state == 'done':
            #         wo.state = 'progress'
            # assign moves; last operation receive all unassigned moves
            # TODO: following could be put in a function as it is similar as code in _workorders_create
            # TODO: only needed when creating new moves
            # moves_raw = production.move_raw_ids.filtered(
            #     lambda move: move.operation_id == operation and move.state not in ('done', 'cancel'))
            # if wo == production.workorder_ids[-1]:
            #     moves_raw |= production.move_raw_ids.filtered(lambda move: not move.operation_id)
            # moves_finished = production.move_finished_ids.filtered(
            #     lambda move: move.operation_id == operation)  # TODO: code does nothing, unless maybe by_products?
            # moves_raw.mapped('move_lot_ids').write({'workorder_id': wo.id})
            # (moves_finished + moves_raw).write({'workorder_id': wo.id})
            # if wo.move_raw_ids.filtered(lambda x: x.product_id.tracking != 'none') and not wo.active_move_lot_ids:
            #     wo._generate_lot_ids()
        return {}
